package jtg.util;

import java.math.BigDecimal;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class NumericalUtil {
    /**判断是否是一个数字
     * */
    public static boolean isNumerical(String input){
        Pattern pattern = Pattern.compile("^[+-]?(\\d+(\\.\\d*)?|\\.\\d+)([eE][+-]?\\d+)?$");
        Matcher matcher = pattern.matcher(input);
        return matcher.find();
    }

    /**判断是否是一个float/long==>以f/l结尾
     * */
    public static boolean isFloatOrLong(String input){
        Pattern pattern = Pattern.compile("^[+-]?(\\d+(\\.\\d*)?|\\.\\d+)([eE][+-]?\\d+)?[LlFf]$");
        Matcher matcher = pattern.matcher(input);
        return matcher.find();
    }

    /**判断一个字符串是否是一个科学计数法。比数学中的判定条件更加宽泛
     * */
    public static boolean isScientificNotation(String input) {
        Pattern pattern = Pattern.compile("^[+-]?[0-9]*\\.?[0-9]+([eE][+-]?[0-9]+)?$");
        Matcher matcher = pattern.matcher(input);
        return matcher.find();
    }

    /**将一个科学计数法转为普通数字
     * */
    public static String convertScientificToDecimal(String scientificNotation) {
        // 使用BigDecimal解析科学计数法的字符串
        BigDecimal bigDecimal = new BigDecimal(scientificNotation);
        // 使用toPlainString()得到非科学计数法形式的字符串
        return bigDecimal.toPlainString();
    }

    /**判断是否是负数（非科学计数法的计数方式）
     * */
    public static boolean isNegative(String input){
        Pattern pattern = Pattern.compile("^-\\d+(\\.\\d+)?$");
        Matcher matcher = pattern.matcher(input);
        return matcher.find();
    }
    /**如果是负数，将其转为减法
     * */
    public static String negativeToMinus(String input,String preInput){
        if (preInput.equals("")||isBinaryOperator(preInput))
            return "( 0 - "+input.substring(1)+" )";
        return input;
    }



    /**数字优化
     * 将数字转换为使用于z3求解的形式
     * */
    public static String numericalOptimizer(String input){
        String[] inputItem = input.split(" ");
        System.out.println(inputItem.length);
        StringBuilder result = new StringBuilder();
        String item = "";
        String preItem = "";
        for (int i = 0;i<inputItem.length;i++){
            item = inputItem[i];
            if (item.equals(""))
                continue;
            if (isFloatOrLong(item))
                item = item.substring(0,item.length()-1);
            if (isScientificNotation(item)){
                item = convertScientificToDecimal(item);
                if (item.startsWith("-"))
                    item = negativeToMinus(item,preItem);
            }else if (isNegative(item)){
                item = negativeToMinus(item,preItem);
            }

            if (result.toString().equals(""))
                result = new StringBuilder(item);
            else
                result.append(" ").append(item);

            preItem = item;
        }
        return result.toString();
    }

    /**判断是否是二元操作符，注意，此主要用于辅助判断‘-’是负号还是减号===>所以，不包含‘)’
     * */
    public static boolean isBinaryOperator(String input){
        switch (input){
            case "+":
            case "-":
            case "cmpl":
            case "cmpg":
            case "cmp":
            case "*":
            case "/":
            case "%":
            case "^":
            case "(":
//            case ")":
            case "&":
            case "|":
            case "&&":
            case "||":
            case "!||":
            case "==":
            case "=":
            case "!=":
            case "<>":
            case "≠":
            case ">":
            case "<":
            case ">=":
            case "≥":
            case "<=":
            case "≤":
            case "<<":
            case ">>":
                return true;
            default:
                return false;
        }
    }
    public static void main(String[] args) {
        String s = "i0 cmp   -1.1113e-12 < 0";
        System.out.println(numericalOptimizer(s));
        System.out.println(isNumerical("1e-12"));
        System.out.println(isFloatOrLong("-1.2e-2f"));
    }
}
